//
//  ViewController.m
//  Filter
//
//  Created by iptv-macmini on 2020/7/8.
//  Copyright © 2020 iptv-macmini. All rights reserved.
//

#import "ViewController.h"
#import "TZImagePickerController.h"

#define Mask8(x)  (  (x) & 0xFF )

#define R(x)  ( Mask8(x) )
#define G(x)  ( Mask8(x >> 8 )  )
#define B(x)  ( Mask8(x >> 16)  )
#define A(x)  ( Mask8(x >> 24)  )

#define RGBAMake(r, g, b, a)  (  Mask8(r) | Mask8(g) << 8 | Mask8(b) << 16 | Mask8(a) << 24 )

@interface ViewController ()<TZImagePickerControllerDelegate,UIImagePickerControllerDelegate,UINavigationControllerDelegate>
@property (weak, nonatomic) IBOutlet UISegmentedControl *segmentedControl;
@property (weak, nonatomic) IBOutlet UISlider *slider;
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@property (nonatomic, strong) UIImagePickerController *imagePickerVc;
@property (nonatomic, strong) PHAsset *imgAsset;
@property (nonatomic, strong) UIImage *baseImg;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
}
- (UIImagePickerController *)imagePickerVc {
    if (_imagePickerVc == nil) {
        _imagePickerVc = [[UIImagePickerController alloc] init];
        _imagePickerVc.delegate = self;
        // set appearance / 改变相册选择页的导航栏外观
        _imagePickerVc.navigationBar.barTintColor = self.navigationController.navigationBar.barTintColor;
        _imagePickerVc.navigationBar.tintColor = self.navigationController.navigationBar.tintColor;
        UIBarButtonItem *tzBarItem, *BarItem;
        tzBarItem = [UIBarButtonItem appearanceWhenContainedInInstancesOfClasses:@[[TZImagePickerController class]]];
        BarItem = [UIBarButtonItem appearanceWhenContainedInInstancesOfClasses:@[[UIImagePickerController class]]];
        NSDictionary *titleTextAttributes = [tzBarItem titleTextAttributesForState:UIControlStateNormal];
        [BarItem setTitleTextAttributes:titleTextAttributes forState:UIControlStateNormal];
    }
    return _imagePickerVc;
}

- (IBAction)choicePhoto:(id)sender {
    TZImagePickerController *imagePickerVc = [[TZImagePickerController alloc] initWithMaxImagesCount:100 columnNumber:4 delegate:self pushPhotoPickerVc:YES];
    imagePickerVc.isSelectOriginalPhoto = YES;
    imagePickerVc.allowTakePicture = NO; // 在内部显示拍照按钮
    imagePickerVc.allowTakeVideo = NO;   // 在内部显示拍视频按钮
    imagePickerVc.iconThemeColor = [UIColor colorWithRed:31 / 255.0 green:185 / 255.0 blue:34 / 255.0 alpha:1.0];
    imagePickerVc.showPhotoCannotSelectLayer = YES;
    imagePickerVc.cannotSelectLayerColor = [[UIColor whiteColor] colorWithAlphaComponent:0.8];
    [imagePickerVc setPhotoPickerPageUIConfigBlock:^(UICollectionView *collectionView, UIView *bottomToolBar, UIButton *previewButton, UIButton *originalPhotoButton, UILabel *originalPhotoLabel, UIButton *doneButton, UIImageView *numberImageView, UILabel *numberLabel, UIView *divideLine) {
        [doneButton setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
    }];
    // 3. 设置是否可以选择视频/图片/原图
    imagePickerVc.allowPickingVideo = NO;
    imagePickerVc.allowPickingImage = YES;
    // 4. 照片排列按修改时间升序
    imagePickerVc.sortAscendingByModificationDate = YES;
    imagePickerVc.showSelectBtn = NO;
    imagePickerVc.allowCrop = NO;
    imagePickerVc.needCircleCrop = NO;
    imagePickerVc.scaleAspectFillCrop = YES;
    
    imagePickerVc.statusBarStyle = UIStatusBarStyleLightContent;
    
    // 设置是否显示图片序号
    imagePickerVc.showSelectedIndex = NO;
    
    __weak typeof(self) weakSelf = self;
    [imagePickerVc setDidFinishPickingPhotosHandle:^(NSArray<UIImage *> *photos, NSArray *assets, BOOL isSelectOriginalPhoto) {
        __strong typeof(weakSelf) strongSelf = weakSelf;
        strongSelf.imageView.image = (UIImage*)photos[0];
        strongSelf.baseImg = (UIImage*)photos[0];
        strongSelf.imgAsset = (PHAsset*)assets[0];
    }];
    
    imagePickerVc.modalPresentationStyle = UIModalPresentationFullScreen;
    [self presentViewController:imagePickerVc animated:YES completion:nil];
}
- (IBAction)grayPhotoAct:(id)sender {
    CGImageRef imageRef = self.imageView.image.CGImage;
    // 一个字节 = 8bit(位) 每行有 17152 个字节，即每行有 17152 * 8 个位   一个像素有 4 个字节
    size_t width = CGImageGetWidth(imageRef);
    size_t height = CGImageGetHeight(imageRef);
    size_t bitsPerComponent = CGImageGetBitsPerComponent(imageRef);
    size_t bytesPerRow = CGImageGetBytesPerRow(imageRef);
    // 颜色空间
    uint32_t bitmapInfo = CGImageGetBitmapInfo(imageRef);
    CGColorSpaceRef space = CGImageGetColorSpace(imageRef);
    
    //获取每个像素的字节数据集合
    CGDataProviderRef dataProviderRef = CGImageGetDataProvider(imageRef);
    CFDataRef dataRef = CGDataProviderCopyData(dataProviderRef);
    UInt8 * bytesPtr = CFDataGetMutableBytePtr((CFMutableDataRef)dataRef);
    NSUInteger length = CFDataGetLength(dataRef);
    
    // 一个像素由四个字节byte组成
    for (int i = 0; i < length; i += 4) {
        UInt8 red = bytesPtr[i];
        UInt8 green = bytesPtr[i + 1];
        UInt8 blue = bytesPtr[i + 2];
        UInt8 average = (red + green + blue) / 3;
        bytesPtr[i] = average;
        bytesPtr[i + 1] = average;
        bytesPtr[i + 2] = average;
    }
    
    CGContextRef imageContextRef = CGBitmapContextCreate(bytesPtr, width, height, bitsPerComponent, bytesPerRow, space, bitmapInfo);
    CGImageRef finalImageRef = CGBitmapContextCreateImage(imageContextRef);
    UIImage * finalImage = [UIImage imageWithCGImage:finalImageRef];
    self.imageView.image = finalImage;
    
    CGImageRelease(finalImageRef);
    CGContextRelease(imageContextRef);
    CFRelease(dataRef);
}

- (IBAction)rgbSegmentedControlAct:(UISegmentedControl*)sender {
    NSArray *cifilter = [CIFilter filterNamesInCategory:kCICategoryBuiltIn];
    
    NSLog(@"FilterName:\n%@ %ld", cifilter,cifilter.count);//显示所有过滤器名字
    for (NSString *filterName in cifilter) {
        CIFilter *fltr = [CIFilter filterWithName:filterName];//用一个过滤器名字生成一个过滤器CIFilter对象
        NSLog(@"%@:\n%@", filterName, [fltr attributes]);//这个过滤器支持的属性
    }
}
- (IBAction)rgbVauleChange:(UISlider*)sender {
}
- (IBAction)addFilterAct:(id)sender {
    [self RGBChange];
    
    UIImage * imageInput = self.imageView.image;
    CIImage * image = [CIImage imageWithCGImage:imageInput.CGImage];
    // 创建图形上下文
    CIContext * context = [CIContext contextWithOptions:nil];
    // 创建自定义参数字典
//    NSDictionary * param = [NSDictionary dictionaryWithObject:CIDetectorAccuracyHigh forKey:CIDetectorAccuracy];
    // 创建识别器对象
    CIDetector *detector = [CIDetector detectorOfType:CIDetectorTypeQRCode
                                              context:context
                                              options:@{CIDetectorAccuracy:CIDetectorAccuracyLow}];
    
    NSArray *features = [detector featuresInImage:image];
    NSMutableArray *content=[[NSMutableArray alloc] init];
    for (CIQRCodeFeature *feature in features) {
        if ([feature isKindOfClass:[CIQRCodeFeature class]]) {
            imageInput =  [self drawBorder:imageInput borderBounds:feature];
            
            [content addObject:feature.messageString];
        }
    }
    self.imageView.image = imageInput;
    NSLog(@"%@",content);
}

- (UIImage*)drawBorder:(UIImage*)image borderBounds:(CIQRCodeFeature*)feature{
    CGSize size = image.size;
    //开启图形上下文
    UIGraphicsBeginImageContext(size);
    //绘制大图片
    [image drawInRect:CGRectMake(0, 0, size.width, size.height)];
    //绘制边框 因为识别出来的bounds坐标与ImageView的坐标系不同所以要翻转
    
    CGContextRef context = UIGraphicsGetCurrentContext();
    //翻转坐标系
    CGContextScaleCTM(context, 1, -1);
    CGContextTranslateCTM(context,0, -size.height);
    
    UIBezierPath *path = [UIBezierPath bezierPathWithRect:feature.bounds];
    [[UIColor redColor] setStroke];
    path.lineWidth = 5;
    [path stroke];
    //获取返回图片
    UIImage *resultImage = UIGraphicsGetImageFromCurrentImageContext();
    //关闭图形上下文
    UIGraphicsEndImageContext();
    //返回图片
    return resultImage;
}

- (void)RGBChange
{
    UIGraphicsBeginImageContext(CGSizeMake(self.imageView.image.size.width, self.imageView.image.size.height));
    CGContextRef imageContextRef = UIGraphicsGetCurrentContext();
    [self.imageView.image drawInRect:CGRectMake(0, 0, self.imageView.image.size.width, self.imageView.image.size.height)];
    //红色滤镜
    UIColor *color = [UIColor clearColor];
    switch (self.segmentedControl.selectedSegmentIndex) {
        case 0:
            color = [UIColor colorWithRed:1 green:0 blue:0 alpha:self.slider.value];
            break;
        case 1:
            color = [UIColor colorWithRed:0 green:1 blue:0 alpha:self.slider.value];
            break;
        case 2:
            color = [UIColor colorWithRed:0 green:0 blue:1 alpha:self.slider.value];
            break;
        default:
            break;
    }
    // 给上下文设置颜色
    CGContextSetFillColorWithColor(imageContextRef, color.CGColor);
    // 设置渲染模式
    CGContextSetBlendMode(imageContextRef, kCGBlendModeNormal);
    // 填充上下文
    CGContextFillRect(imageContextRef, CGRectMake(0, 0, self.imageView.image.size.width, self.imageView.image.size.height));
    CGImageRef finalImageRef = CGBitmapContextCreateImage(imageContextRef);
    UIImage * finalImage = [UIImage imageWithCGImage:finalImageRef];
    self.imageView.image = finalImage;
    
    CGImageRelease(finalImageRef);
    CGContextRelease(imageContextRef);
}

- (IBAction)saturationAct:(id)sender {
    CIImage *beginImage = [CIImage imageWithCGImage:self.imageView.image.CGImage];
    CIFilter * filter = [CIFilter filterWithName:@"CIColorControls"];
    [filter setValue:beginImage forKey:kCIInputImageKey];
    //饱和度 0---2 默认为1
    [filter setValue:[NSNumber numberWithFloat:self.slider.value*2] forKey:@"inputSaturation"];
    
    // 得到过滤后的图片
    CIImage *outputImage = [filter outputImage];
    // 转换图片, 创建基于GPU的CIContext对象
    CIContext *context = [CIContext contextWithOptions: nil];
    CGImageRef cgimg = [context createCGImage:outputImage fromRect:[outputImage extent]];
    UIImage *newImg = [UIImage imageWithCGImage:cgimg];
    // 显示图片
    [self.imageView setImage:newImg];
    // 释放C对象
    CGImageRelease(cgimg);
}

- (IBAction)brightnessAct:(id)sender {
    CIImage *beginImage = [CIImage imageWithCGImage:self.imageView.image.CGImage];
    CIFilter * filter = [CIFilter filterWithName:@"CIColorControls"];
    [filter setValue:beginImage forKey:kCIInputImageKey];
    //亮度 -1---1 默认为0
    [filter setValue:[NSNumber numberWithFloat:(self.slider.value-0.5)*2] forKey:@"inputBrightness"];
    
    // 得到过滤后的图片
    CIImage *outputImage = [filter outputImage];
    // 转换图片, 创建基于GPU的CIContext对象
    CIContext *context = [CIContext contextWithOptions: nil];
    CGImageRef cgimg = [context createCGImage:outputImage fromRect:[outputImage extent]];
    UIImage *newImg = [UIImage imageWithCGImage:cgimg];
    // 显示图片
    [self.imageView setImage:newImg];
    // 释放C对象
    CGImageRelease(cgimg);
}

- (IBAction)contrastAct:(id)sender {
    CIImage *beginImage = [CIImage imageWithCGImage:self.imageView.image.CGImage];
    CIFilter * filter = [CIFilter filterWithName:@"CIColorControls"];
    [filter setValue:beginImage forKey:kCIInputImageKey];
    //对比度 0---4 默认为1
    [filter setValue:[NSNumber numberWithFloat:self.slider.value*4.00f] forKey:@"inputContrast"];
    
    // 得到过滤后的图片
    CIImage *outputImage = [filter outputImage];
    // 转换图片, 创建基于GPU的CIContext对象
    CIContext *context = [CIContext contextWithOptions: nil];
    CGImageRef cgimg = [context createCGImage:outputImage fromRect:[outputImage extent]];
    UIImage *newImg = [UIImage imageWithCGImage:cgimg];
    // 显示图片
    [self.imageView setImage:newImg];
    // 释放C对象
    CGImageRelease(cgimg);
}

- (IBAction)configAct:(id)sender {
    if (!self.imgAsset) {
        UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"" message:@"请添加照片" preferredStyle:UIAlertControllerStyleAlert];
        UIAlertAction *alertAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {}];
        [alert addAction:alertAction];
        [self presentViewController:alert animated:YES completion:nil];
        return;
    }
    // 2、获取PHContentEditingInput对象
    __weak typeof(self) weakSelf = self;
    PHContentEditingInputRequestOptions * requestOptions = [[PHContentEditingInputRequestOptions alloc] init];
//    // 该方法只有在已经存在PHAdjustmentData的情况下才会被调用
//    requestOptions.canHandleAdjustmentData = ^BOOL(PHAdjustmentData * _Nonnull adjustmentData) {
//        NSLog(@"formatIdentifier:%@,formatVersion:%@", adjustmentData.formatIdentifier, adjustmentData.formatVersion);
//        return YES;
//    };
    [self.imgAsset requestContentEditingInputWithOptions:requestOptions completionHandler:^(PHContentEditingInput * _Nullable contentEditingInput, NSDictionary * _Nonnull info)
     {
        __strong typeof(weakSelf) self = weakSelf;
        // 3、创建PHAdjustmentdata，可以在data参数里设置要做的操作，比如过滤等，可以是一个序列串，但是这里的长度是有限制的
        PHAdjustmentData * adjustData = [[PHAdjustmentData alloc] initWithFormatIdentifier:self.imgAsset.localIdentifier formatVersion:@"1.0" data:[@"ceshi" dataUsingEncoding:NSUTF8StringEncoding]];
        // 4、初始化PHContentEditingOutput对象
        PHContentEditingOutput * output = [[PHContentEditingOutput alloc] initWithContentEditingInput:contentEditingInput];
        output.adjustmentData = adjustData;
        
        //⚠️这里为什么一定要用UIImageJPEGRepresentation才能成功，而UIImagePNGRepresentation会失败，生成的数据是正确的，但是相册相应的资源无法更新???
        // 因为这个和renderedContentURL有关，图片的输出只能是JPEG格式，video只能是.mov格式输出
        // 对于Live Photo，调用saveLivePhotoToOutput:options:completionHandler:方法保存和更新
        BOOL isSuccess = [UIImageJPEGRepresentation(self.imageView.image, 1) writeToURL:output.renderedContentURL atomically:NO];
        if (isSuccess) {
            NSLog(@"写入成功");
        } else {
            NSLog(@"写入失败");
        }
        // 5、赋值更新
        [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
            __strong typeof(weakSelf) self = weakSelf;
            // 使用PHAssetChangeRequest
            PHAssetChangeRequest * changeRequest = [PHAssetChangeRequest changeRequestForAsset: self.imgAsset];
            PHObjectPlaceholder *placeholder = [changeRequest placeholderForCreatedAsset];
            PHAssetCollection *assetCollection = [self getCurrentPhotoCollectionWithTitle:@"菜单"];
            PHAssetCollectionChangeRequest *collectionRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:assetCollection];
            [collectionRequest addAssets:@[placeholder]];
//            changeRequest.contentEditingOutput = output;
        } completionHandler:^(BOOL success, NSError * _Nullable error) {
            if (success) {
                NSLog(@"编辑内容成功");
            } else {
                NSLog(@"编辑内容失败:%@", error);
            }
        }];
    }];
    
}

- (PHAssetCollection *)getCurrentPhotoCollectionWithTitle:(NSString *)collectionName {
     
     // 1. 创建搜索集合
     PHFetchResult *result = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];
     
     // 2. 遍历搜索集合并取出对应的相册
     for (PHAssetCollection *assetCollection in result) {
         
         if ([assetCollection.localizedTitle containsString:collectionName]) {
             return assetCollection;
         }
     }
     
     return nil;
 }

- (IBAction)cancelAct:(id)sender {
    self.imageView.image = self.baseImg;
}

#pragma mark - UIImagePickerController

- (void)takePhoto {
    AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
    if (authStatus == AVAuthorizationStatusRestricted || authStatus == AVAuthorizationStatusDenied) {
        // 无相机权限 做一个友好的提示
        UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"无法使用相机" message:@"请在iPhone的""设置-隐私-相机""中允许访问相机" preferredStyle:UIAlertControllerStyleAlert];
        [alertController addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil]];
        [alertController addAction:[UIAlertAction actionWithTitle:@"设置" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
            [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
        }]];
        [self presentViewController:alertController animated:YES completion:nil];
    } else if (authStatus == AVAuthorizationStatusNotDetermined) {
        // fix issue 466, 防止用户首次拍照拒绝授权时相机页黑屏
        [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
            if (granted) {
                dispatch_async(dispatch_get_main_queue(), ^{
                    [self takePhoto];
                });
            }
        }];
        // 拍照之前还需要检查相册权限
    }else if ([PHPhotoLibrary authorizationStatus] == 0) { // 未请求过相册权限
        [[TZImageManager manager] requestAuthorizationWithCompletion:^{
            [self takePhoto];
        }];
    }
}

- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
    if ([picker isKindOfClass:[UIImagePickerController class]]) {
        [picker dismissViewControllerAnimated:YES completion:nil];
    }
}
@end
